// ignore_for_file: camel_case_types

/*
 * @Author: ZephyrGao
 * @Date: 2023-11-08 07:51:01
 * @Description: 
 * Copyright (c) 2023 by ZephyrGao, All Rights Reserved. 
 */

import 'dart:math' as math;
import 'package:cn_flutter_ui/src/constants/vant4_constant.dart';

import 'package:flutter/material.dart';

enum VanLoadingType {
  circular, //线性圆形
  spinner, // 菊花
}

class VanLoading extends StatefulWidget {
  const VanLoading({
    super.key,
    this.color = Vant4LoadingConstant.color,
    this.type = VanLoadingType.circular,
    this.size = Vant4LoadingConstant.size,
    this.text,
    this.textSize = Vant4LoadingConstant.textSize,
    this.textColor = Vant4LoadingConstant.textColor,
    this.vertical = false,
    this.defaultSlot,
    this.iconSlot,
    this.strokeWidth = Vant4LoadingConstant.strokeWidth,
  });

  /// 颜色
  final Color? color;

  /// type  默认 `VanLoadingType.circular`
  final VanLoadingType type;

  /// 加载图标大小，默认30px
  final double size;

  /// 文字
  final String? text;

  /// 文字大小 默认14px
  final double textSize;

  /// 文字颜色
  final Color? textColor;

  /// 是否垂直排列图标和文字内容 默认false
  final bool vertical;

  /// 加载文案插槽
  final Widget? defaultSlot;

  /// 定义加载图标插槽
  final Widget? iconSlot;

  /// 定义加载图标插槽
  final double strokeWidth;

  @override
  State<VanLoading> createState() => _VanLoadingState();
}

class _VanLoadingState extends State<VanLoading>
    with SingleTickerProviderStateMixin {
  late AnimationController _animationController;

  @override
  void initState() {
    super.initState();
    _animationController = AnimationController(
      duration: const Duration(milliseconds: 1500),
      vsync: this,
    )..repeat();
  }

  @override
  void dispose() {
    _animationController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Flex(
      mainAxisSize: MainAxisSize.min,
      direction: widget.vertical ? Axis.vertical : Axis.horizontal,
      children: [
        _iconSlot(),
        widget.defaultSlot != null ||
                (widget.text != null && widget.text!.isNotEmpty)
            ? (widget.vertical
                ? Vant4LoadingConstant.baseMarginTop
                : Vant4LoadingConstant.baseMarginLeft)
            : Vant4CommonConstant.empty,
        _defaultSlot(),
      ],
    );
  }

  // 自定义文案
  Widget _defaultSlot() {
    return widget.defaultSlot ??
        (widget.text == null
            ? Vant4CommonConstant.empty
            : Text(
                widget.text!,
                style: TextStyle(
                    color: widget.textColor,
                    fontSize: widget.textSize,
                    fontWeight: FontWeight.w400),
              ));
  }

  // 自定义加载图标
  Widget _iconSlot() {
    if (widget.iconSlot != null) {
      return RotationTransition(
          turns: _animationController, child: widget.iconSlot!);
    }
    return Container(
      padding: EdgeInsets.all(widget.size * 0.1),
      width: widget.size,
      height: widget.size,
      child: widget.type == VanLoadingType.circular
          ? CircularProgressIndicator(
              color: widget.color,
              strokeWidth: widget.strokeWidth,
            )
          : VantActivityIndicator(
              strokeWidth: widget.strokeWidth,
              size: widget.size,
              color: widget.color ?? Vant4LoadingConstant.color,
            ),
    );
  }
}

class VantActivityIndicator extends StatefulWidget {
  const VantActivityIndicator(
      {super.key,
      this.size = Vant4LoadingConstant.size,
      this.color = Vant4LoadingConstant.color,
      this.animating = true,
      this.strokeWidth = 1});
  final bool animating;
  final double size;
  final Color color;
  final double strokeWidth;

  @override
  VantLoaderState createState() => VantLoaderState();
}

class VantLoaderState extends State<VantActivityIndicator>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;

  @override
  void initState() {
    super.initState();

    _controller = AnimationController(
      duration: const Duration(seconds: 1),
      vsync: this,
    );

    if (widget.animating) {
      _controller.repeat();
    }
  }

  @override
  void didUpdateWidget(covariant VantActivityIndicator oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (widget.animating != oldWidget.animating) {
      if (widget.animating) {
        _controller.repeat();
      } else {
        _controller.stop();
      }
    }
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      height: widget.size,
      width: widget.size,
      child: CustomPaint(
        painter: _vantActivityIndicatorPainter(
            position: _controller,
            activeColor: widget.color,
            radius: widget.size / 2,
            progress: 1,
            strokeWidth: widget.strokeWidth / 2),
      ),
    );
  }
}

// const double _kDefaultIndicatorRadius = 15.0;

const double _kTwoPI = math.pi * 2.0;

const List<int> _kAlphaValues = <int>[
  16,
  15,
  14,
  13,
  12,
  11,
  10,
  9,
  8,
  7,
  6,
  5
];

/// The alpha value that is used to draw the partially revealed ticks.
const int _partiallyRevealedAlpha = 16;

class _vantActivityIndicatorPainter extends CustomPainter {
  // https://blog.51cto.com/xace/4793511
  _vantActivityIndicatorPainter({
    required this.position,
    required this.activeColor,
    required this.radius,
    required this.progress,
    required this.strokeWidth,
  })  : tickFundamentalRRect = RRect.fromLTRBXY(
          -1,
          -radius / 2,
          1,
          -radius,
          1,
          1,
        ),
        super(repaint: position);

// RRect.fromLTRBXY(
//             -strokeWidth, -2, strokeWidth, -radius, strokeWidth, strokeWidth)
  final Animation<double> position;
  final Color activeColor;
  final double radius;
  final double progress;
  final double strokeWidth;

  final RRect tickFundamentalRRect;

  @override
  void paint(Canvas canvas, Size size) {
    final Paint paint = Paint();

    final int tickCount = _kAlphaValues.length;

    canvas.save();
    canvas.translate(size.width / 2.0, size.height / 2.0);

    final int activeTick = (tickCount * position.value).floor();
    //
    for (int i = 0; i < tickCount * progress; ++i) {
      final int t = (i - activeTick) % tickCount;
      double opacity = 0.0;
      opacity = 1 / _partiallyRevealedAlpha * _kAlphaValues[t];
      paint.color = activeColor.withOpacity(progress < 1 ? 1 : opacity);

      // paint.color = activeColor
      //     .withAlpha(progress < 1 ? _partiallyRevealedAlpha : _kAlphaValues[t]);

      canvas.drawRRect(tickFundamentalRRect, paint);
      canvas.rotate(_kTwoPI / tickCount);
    }

    canvas.restore();
  }

  @override
  bool shouldRepaint(_vantActivityIndicatorPainter oldPainter) {
    return oldPainter.position != position ||
        oldPainter.activeColor != activeColor ||
        oldPainter.progress != progress;
  }
}
